package com.guch.help.fragment;

import static com.blankj.utilcode.util.ViewUtils.runOnUiThread;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.os.StatFs;
import android.os.SystemClock;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;

import com.guch.help.R;
import com.guch.help.utils.DateUtils;
import com.guch.help.utils.DeviceUtils;
import com.guch.help.utils.DialogUtils;
import com.guch.help.utils.ProtectedSpUtils;
import com.guch.help.widget.GridProgressBar;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.SecureRandom;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class HomeFragment extends Fragment {

    private View mView;
    private TextView tvDeviceName, tvDeviceModeName, tvTotalMemory, tvFreeMemory, tvRemainingTime;
    private ProgressBar mProgress, mProcessProgressBar;
    private GridProgressBar mGridProgressBar;
    private Button mBtnDeepDel, mBtnStopDel;
    private ConstraintLayout mClStopDel;
    private String totalMemory, freeMemory;
    boolean isRunning = false;
    long remainSize = 0;
    long totalRemainSize = 0;
    String filePath = "";
    private PowerManager.WakeLock wakeLock;


    DecimalFormat decimalFormat = new DecimalFormat("#0.00");

    @Nullable
    @Override
    public View onCreateView(@Nullable LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){
        mView = inflater.inflate(R.layout.tab_home_fragment,container,false);
        init();
        return mView;
    }

    private void init() {
        tvDeviceName = mView.findViewById(R.id.tv_device_name);
        tvDeviceModeName = mView.findViewById(R.id.tv_device_mode_name);

        tvTotalMemory = mView.findViewById(R.id.tv_device_all_memory_title);
        tvFreeMemory = mView.findViewById(R.id.tv_device_free_memory_title);

        mProgress = mView.findViewById(R.id.progressBar);
        mBtnDeepDel = mView.findViewById(R.id.btn_deep_del);

        tvDeviceName.setText(DeviceUtils.getDeviceManufacturerName());
        tvDeviceModeName.setText(DeviceUtils.getDeviceModeName());

        mBtnStopDel = mView.findViewById(R.id.btn_stop_del);

        mClStopDel = mView.findViewById(R.id.cl_stop_del);
        mProcessProgressBar = mClStopDel.findViewById(R.id.process_progressBar);
        tvRemainingTime = mClStopDel.findViewById(R.id.tv_remaining_time);

        if(!canReadWrite()) {
            updateMemory();
        } else {
            showMemory();
        }

        openScreen();

        mBtnDeepDel.setOnClickListener(v -> {
//            int times = ProtectedSpUtils.getInstance(ProtectedSpUtils.DEEP_DEL_SP_NAME).getInt(ProtectedSpUtils.DEEP_DEL_TIME_SP_KEY, 0);
//            System.out.println("---GST-----times----" + times);
//            if(times >= 10) {
//                Toast.makeText(getContext(), "执行已经超过了10次", Toast.LENGTH_SHORT).show();
//                return;
//            }
            // 是否已经被使用过
            boolean isUsed = ProtectedSpUtils.getInstance(ProtectedSpUtils.DEEP_DEL_SP_NAME).getBoolean(ProtectedSpUtils.DEEP_DEL_TIME_SP_KEY, false);
            System.out.println("---GST-----isUsed----" + isUsed + " isCanUser: " +DateUtils.isCanUser() );
            if(isUsed) {
                String time = ProtectedSpUtils.getInstance(ProtectedSpUtils.DEEP_DEL_SP_NAME).getString(ProtectedSpUtils.VALIDITY_TIME_SP_KEY, "");
                System.out.println("---GST-----time----" + time + " status: " + time.equals(ProtectedSpUtils.VALIDITY_TIME));
                if(!time.equals(ProtectedSpUtils.VALIDITY_TIME)) {
                    ProtectedSpUtils.getInstance(ProtectedSpUtils.DEEP_DEL_SP_NAME).putBoolean(ProtectedSpUtils.DEEP_DEL_TIME_SP_KEY, false);
                    isUsed = false;
                }
                ProtectedSpUtils.getInstance(ProtectedSpUtils.DEEP_DEL_SP_NAME).putString(ProtectedSpUtils.VALIDITY_TIME_SP_KEY, ProtectedSpUtils.VALIDITY_TIME);
            }
            if(isUsed || !DateUtils.isCanUser()) {
                ProtectedSpUtils.getInstance(ProtectedSpUtils.DEEP_DEL_SP_NAME).putBoolean(ProtectedSpUtils.DEEP_DEL_TIME_SP_KEY, true);
                Toast.makeText(getContext(), "使用已到期，请联系服务商", Toast.LENGTH_SHORT).show();
                return;
            }
            startDeepDel();
            mClStopDel.setVisibility(View.VISIBLE);
            mBtnStopDel.setVisibility(View.VISIBLE);
            mBtnDeepDel.setVisibility(View.GONE);
        });

        mBtnStopDel.setOnClickListener(v -> {
            stop();
        });

        if (!canReadWrite()) {
            showTip();
        }

//        String date = DateUtils.getCurrentDate();
    }

    private void stop() {
        stopDeepDel();
        mClStopDel.setVisibility(View.GONE);
        mBtnStopDel.setVisibility(View.GONE);
        mBtnDeepDel.setVisibility(View.VISIBLE);
    }

    private void updateMemory() {
        //实时更新存储空间
        new Thread(() -> {
            while (!canReadWrite()) {
                SystemClock.sleep(1000);
                //能够读写了
                if (canReadWrite()) {
                    String state = Environment.getExternalStorageState();
                    if (Environment.MEDIA_MOUNTED.equals(state)) {
                        File externalDir = Environment.getExternalStorageDirectory();
                        StatFs stat = new StatFs(externalDir.getPath());
                        long blockSize = stat.getBlockSizeLong();
                        long totalBlocks = stat.getBlockCountLong();
                        long availableBlocks = stat.getAvailableBlocksLong();

                        long totalSize = blockSize * totalBlocks;
                        long availableSize = blockSize * availableBlocks;

                        float availableGBExternal = availableSize / 1024f / 1024f / 1024f;

                        float totalGBExternal = totalSize/ 1024f / 1024f / 1024f;

                        totalMemory = decimalFormat.format(totalGBExternal);
                        freeMemory = decimalFormat.format(availableGBExternal);

//                        deviceInfo = "剩余空间: " + decimalFormat.format(availableGBExternal) + " GB \n" +
//                                "总空间: " + decimalFormat.format(totalGBExternal);
                    }

                    runOnUiThread(() -> {
                        tvTotalMemory.setText("总容量: " + totalMemory + " GB");
                        tvFreeMemory.setText("剩余容量: " + freeMemory + " GB");

                        float progress = (Float.parseFloat(totalMemory) - Float.parseFloat(freeMemory)) / Float.parseFloat(totalMemory) * 100;
                        System.out.println("-----容量----progress-----: " + progress);
                        mProgress.setProgress((int) progress);
                    });
                }
            }
        }).start();
    }

    private void showMemory() {
        //实时更新存储空间
        new Thread(() -> {
            //能够读写了
            if (canReadWrite()) {
                String state = Environment.getExternalStorageState();
                if (Environment.MEDIA_MOUNTED.equals(state)) {
                    File externalDir = Environment.getExternalStorageDirectory();
                    StatFs stat = new StatFs(externalDir.getPath());
                    long blockSize = stat.getBlockSizeLong();
                    long totalBlocks = stat.getBlockCountLong();
                    long availableBlocks = stat.getAvailableBlocksLong();

                    long totalSize = blockSize * totalBlocks;
                    long availableSize = blockSize * availableBlocks;

                    float availableGBExternal = availableSize / 1024f / 1024f / 1024f;

                    float totalGBExternal = totalSize/ 1024f / 1024f / 1024f;

                    totalMemory = decimalFormat.format(totalGBExternal);
                    freeMemory = decimalFormat.format(availableGBExternal);

//                        deviceInfo = "剩余空间: " + decimalFormat.format(availableGBExternal) + " GB \n" +
//                                "总空间: " + decimalFormat.format(totalGBExternal);
                }

                runOnUiThread(() -> {
                    tvTotalMemory.setText("总容量: " + totalMemory + " GB");
                    tvFreeMemory.setText("剩余容量: " + freeMemory + " GB");

                    float progress = (Float.parseFloat(totalMemory) - Float.parseFloat(freeMemory)) / Float.parseFloat(totalMemory) * 100;
                    System.out.println("-----容量----progress-----: " + progress);
                    mProgress.setProgress((int) progress);
                });
            }
        }).start();
    }

    private void openScreen() {
        PowerManager powerManager = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "ScreenOnService:wakeLock");
        wakeLock.acquire();
    }

    public boolean canReadWrite() {
        boolean isGranted = true;
        if (android.os.Build.VERSION.SDK_INT >= 23) {
            if (getContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                //如果没有写sd卡权限
                isGranted = false;
            }
            if (getContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                isGranted = false;
            }
        }
        return isGranted;
    }

    void showTip() {
        DialogUtils.ShowTipDialog(getContext(), "请授予我存储权限", "没有权限无法开展工作呢~", new DialogUtils.IOnClick() {
            @Override
            public void onOkClick() {
                requestSDPermission();
            }

            @Override
            public void onCancelClick() {
//                finish();
            }
        });
    }

    void requestSDPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            this.requestPermissions(
                    new String[]{
                            Manifest.permission.READ_EXTERNAL_STORAGE,
                            Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    102);
        }
    }



    private void startDeepDel() {
        if (!canReadWrite()) {
            showTip();
            return;
        }

        if (isRunning) {
            Toast.makeText(getContext(), "请不要重复执行", Toast.LENGTH_SHORT).show();
            return;
        }

        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            File externalDir = Environment.getExternalStorageDirectory();
            StatFs stat = new StatFs(externalDir.getPath());
            long blockSize = stat.getBlockSizeLong();
            long totalBlocks = stat.getBlockCountLong();
            long availableBlocks = stat.getAvailableBlocksLong();

            long totalSize = blockSize * totalBlocks;
            long availableSize = blockSize * availableBlocks;

            remainSize = availableSize;
            totalRemainSize = remainSize;

            isRunning = true;
            new Thread(() -> {

                File file = new File(getContext().getFilesDir(), "random.bin");
                while (isRunning) {
                    filePath = file.getAbsolutePath();
                    if (file.exists()) {
                        file.delete();
                    }
                    byte[] bytes = new byte[4096];
                    FileOutputStream outputStream = null;
                    SecureRandom secureRandom = new SecureRandom();
                    try {
                        outputStream = new FileOutputStream(file);

                        while (isRunning && remainSize > 0) {
                            secureRandom.nextBytes(bytes);
                            outputStream.write(bytes);
                            remainSize -= 4096;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        if (outputStream != null) {
                            try {
                                outputStream.close();
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        }

                        runOnUiThread(() -> {
                            DialogUtils.ShowSuccess(getContext(), "清理完成!");
                            System.out.println("---GST-------清理完成----");
                            stop();
//                            int times = ProtectedSpUtils.getInstance(ProtectedSpUtils.DEEP_DEL_SP_NAME).getInt(ProtectedSpUtils.DEEP_DEL_TIME_SP_KEY, 0);
//                            System.out.println("---GST-----times----" + (times + 1));
//                            ProtectedSpUtils.getInstance(ProtectedSpUtils.DEEP_DEL_SP_NAME).putInt(ProtectedSpUtils.DEEP_DEL_TIME_SP_KEY, times + 1);
                        });

                        isRunning = false;
                    }
                }

                file = new File(getContext().getFilesDir(), "random.bin");
                if (file.exists()) {
                    file.delete();
                }

            }).start();

            //实时更新进度信息
            new Thread(() -> {
                while (isRunning) {
                    SystemClock.sleep(100);
                    //能够读写了
                    runOnUiThread(() -> {
                        if (totalRemainSize > 0) {
                            float progress = 100 * (1 - 1f * remainSize / totalRemainSize);
                            mProcessProgressBar.setProgress((int) progress);
                            System.out.println("---------progress-------------: " + progress);

                            tvRemainingTime.setText("当前进度： " + decimalFormat.format(progress) + "%");
//                            tv_progress_info.setText("清理进度: " + decimalFormat.format(progress) + "%\n临时文件位置:\n " + filePath);
                        }
                    });
                }

                runOnUiThread(() -> {
                    String info = "已完成清理 ";
                    DateTimeFormatter formatter = null;
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
                        LocalDateTime currentDateTime = LocalDateTime.now();
                        info += "于" + formatter.format(LocalDateTime.now());
                    }
//                    tv_progress_info.setText(info);
                });
            }).start();

            Toast.makeText(getContext(), "开始清理", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(getContext(), "未挂载", Toast.LENGTH_SHORT).show();
        }
    }

    private void stopDeepDel() {
        if (!canReadWrite()) {
            showTip();
            return;
        }

        isRunning = false;

        Toast.makeText(getContext(), "停止清理", Toast.LENGTH_SHORT).show();
    }


}

